package org.research.sdbx.datetime;

import static org.research.sdbx.datetime.DateFormat.parse;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static java.util.Calendar.YEAR;
import static java.util.Calendar.MONTH;
import static java.util.Calendar.DAY_OF_MONTH;
import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.MINUTE;
import static java.util.Calendar.SECOND;
import static java.util.Calendar.MILLISECOND;
import static java.util.Calendar.DAY_OF_WEEK;

class TimeInstanceCalendar implements TimeInstance {
	
	private final Log logger = LogFactory.getLog(getClass());
	
	private static String[] formats = new String[]{"MM/dd/yyyy","MM-dd-yyyy"};
	private Calendar base;
	
	TimeInstanceCalendar() {
		base = Calendar.getInstance();
	}
	
	TimeInstanceCalendar(Object object, TimeZone timeZone, TimePrecision timePrecision) {
		this();
		setTimeZone(timeZone);
		setTimePrecision(timePrecision);
		if(object instanceof TimeInstance){
			base.setTimeInMillis(((TimeInstance)object).getTimeInMillis());
		} else if(object instanceof Calendar){
			base.setTimeInMillis(((Calendar)object).getTimeInMillis());
		} else if(object instanceof Date){
			base.setTimeInMillis(((Date)object).getTime());
		} else if(object instanceof Long){
			base.setTimeInMillis(((Long)object).longValue());
		} else if(object instanceof TimePrecision){
			setTimePrecision((TimePrecision)object);
		} else if(object instanceof TimeZone){
			setTimeZone((TimeZone)object);
		} else if(object instanceof String){
			boolean matched=false;
			for (int i = 0; i < formats.length; i++) {
				try {
					parse((String)object, formats[i]);
					matched=true;
				} catch (RuntimeException e) {
					logger.warn("Match not found");
				}
			}
			if(!matched){
				if(logger.isFatalEnabled()){logger.fatal("Match not found");}
				throw new RuntimeException("No match found for "+object.toString());
			}
		} else {
			throw new RuntimeException(object.toString()+" not supported");
		}
	}
	
	public TimeInstance addDayOfMonth(int amount) {
		base.add(DAY_OF_MONTH, amount);
		return this;
	}

	public TimeInstance addHourOfDay(int amount) {
		base.add(HOUR_OF_DAY, amount);
		return this;
	}

	public TimeInstance addMillisecond(int amount) {
		base.add(MILLISECOND, amount);
		return this;
	}

	public TimeInstance addMinute(int amount) {
		base.add(MINUTE, amount);
		return this;
	}

	public TimeInstance addMonth(int amount) {
		base.add(MONTH, amount);
		return this;
	}

	public TimeInstance addSecond(int amount) {
		base.add(SECOND, amount);
		return this;
	}

	public TimeInstance addWeek(int amount) {
		base.add(DAY_OF_MONTH, amount*7);
		return this;
	}

	public TimeInstance addYear(int amount) {
		base.add(YEAR, amount);
		return this;
	}

	public boolean after(Calendar calendar) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean after(Date date) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean after(TimeInstance timeInstance) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean after(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean before(Calendar calendar) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean before(Date date) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean before(TimeInstance arg) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean before(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean beforeOrOnStart(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean between(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean betweenInclusive(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean betweenOrOnEnd(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean betweenOrOnStart(TimeRange timeRange) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean equals(TimeInstance timeInstance, TimePrecision precision) {
		// TODO Auto-generated method stub
		return false;
	}

	public int getDayOfMonth() {
		return base.get(DAY_OF_MONTH);
	}

	public DayOfWeek getDayOfWeek() {
		return DayOfWeek.valueOf(base.get(DAY_OF_WEEK));  
	}

	public int getHour() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getHourOfDay() {
		return base.get(HOUR_OF_DAY);
	}

	public int getMillisecond() {
		return base.get(MILLISECOND);
	}

	public int getMinute() {
		return base.get(MINUTE);
	}

	public Month getMonth() {
		return Month.valueOf(base.get(MONTH)+1);
	}

	public int getSecond() {
		return base.get(SECOND);
	}

	public TimeDifference getTimeDifference(TimeInstance timeInstance) {
		// TODO Auto-generated method stub
		return null;
	}

	public int getWeekOfMonth() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getWeekOfYear() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getYear() {
		// TODO Auto-generated method stub
		return 0;
	}

	public TimeInstance setDayOfMonth() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setHour() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setHourOfDay() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setMillisecond() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setMinute() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setMonth() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setSecond() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setWeekOfMonth() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setWeekOfYear() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setYear() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setMonth(Month month) {
		// TODO Auto-generated method stub
		return null;
	}

	public TimePrecision getTimePrecision() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeZone getTimeZone() {
		// TODO Auto-generated method stub
		return null;
	}

	public TimeInstance setTimeZone(TimeZone timeZone) {
		base.setTimeZone(timeZone);
		return this;
	}

	public TimeInstance setTimePrecision(TimePrecision timePrecision) {
		
		switch (timePrecision.getValue()) {
		case MONTH:
			
			break;

		default:
			break;
		}
		
		return null;
	}

	public long getTimeInMillis() {
		// TODO Auto-generated method stub
		return 0;
	}

	
	
}
